package util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import play.libs.WS;
import play.libs.WS.HttpResponse;
import play.libs.WS.WSRequest;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

public class Factual {

	private String url;
	private String apiKey;

	public Factual(String url, String table, String apiKey) {
		this.url = String.format(url, table);
		this.apiKey = apiKey;
	}

	public Map<String, Object> read(String uuid) {
		WSRequest request = WS.url(url + "/read");
		request.setParameter("api_key", apiKey);
		request.setParameter("filters", String.format("{\"uuid\":\"%s\"}", uuid));

		HttpResponse response = request.get();
		try {
			Map<String, Object> entityValues = new HashMap<String, Object>();
			JsonObject content = response.getJson().getAsJsonObject().get(
					"response").getAsJsonObject();

			int rows = content.get("total_rows").getAsInt();
			if (rows != 1)
				return null;

			List<String> fieldList = new ArrayList<String>();
			JsonArray fields = content.get("fields").getAsJsonArray();
			for (JsonElement e : fields)
				fieldList.add(e.getAsString());

			JsonArray data = content.get("data").getAsJsonArray().get(0)
					.getAsJsonArray();

			int i = 0;
			for (JsonElement e : data) {
				String value = (e.isJsonNull()) ? null : e.getAsString();
				entityValues.put(fieldList.get(i), value);
				i++;
			}
			if (entityValues.containsKey("region"))
				entityValues.put("state", entityValues.remove("region")); // Have to rename field.
			return entityValues;
		} catch (NullPointerException e) {
			return null;
		}
	}

	public void write(String subjectKey, Map<String, Object> values) {
		// Have to rename field.
		if (values.containsKey("state"))
			values.put("region", values.remove("state"));
		// Don't send this field to Factual, it's not something we can update.
		values.remove("docid");

		WSRequest request = WS.url(url + "/input");
		request.setParameter("api_key", apiKey);
		request.setParameter("subject_key", subjectKey);
		request.setParameter("values", new Gson().toJson(values));
		request.setParameter("source", "findfood.javadocmd.com");

		request.get();
	}
}
